package com.jayanslow.lighting.server.parser;

import com.jayanslow.lighting.protocol.commands.Net.NetCommand;
import com.jayanslow.lighting.protocol.commands.Net.NetDevice;
import com.jayanslow.lighting.protocol.misc.Bytes;
import com.jayanslow.lighting.protocol.misc.CharacterEncoding;
import com.jayanslow.lighting.server.clients.Client;
import com.jayanslow.lighting.server.clients.ClientManager;

public class NetParser {
	short[] data;
	Client client;
	public short[] startParse(Client client, short[] ss) {
		this.client = client;
		this.data = ss;
		NetCommand cmd = NetCommand.valueOf(ss[0]);
		try {
			switch (cmd) {
				case CONNECT:
					return connect();
				case CONNECT_NAME:
					return connectName();
				case DISCONNECT:
					return disconnect();
				case NAME:
					return changeName();
				case REGISTER:
					return register();
				case UNREGISTER:
					return unregister();
				default:
					return Errors.COMMAND.getArray();
			}
		} catch (Exception e) {
			return Errors.UNKNOWN.getArray();
		}
	}

	private short[] connect() {
		if (data.length != 2) return Errors.FORMAT.getArray();
		short typeS = data[1];
		NetDevice type = NetDevice.valueOf(typeS);
		short id, code = NetCommand.CONNECT.getCode();
		String name = ClientManager.DEFAULT_NAME;
		
		if (type == null) return Errors.UNKNOWN.getArray();
		
		client.connect(type, name);
		
		id = client.getClientId();
		
		return new short[] { code, id };
	}
	private short[] connectName() {
		if (data.length != 14) return Errors.FORMAT.getArray();
		short typeS = data[1];
		NetDevice type = NetDevice.valueOf(typeS);
		short id, code = NetCommand.CONNECT_NAME.getCode();
		
		short[] nameSS = new short[12];
		for (int i = 0; i < nameSS.length; i++) nameSS[i] = data[2 + i];
		String name = CharacterEncoding.CHAR64.encode(Bytes.toBigInteger(nameSS));
		
		if (type == null) return Errors.UNKNOWN.getArray();
		if (name.isEmpty()) name = ClientManager.DEFAULT_NAME;
		
		client.connect(type, name);
		
		id = client.getClientId();
		
		return new short[] { code, id };
	}
	private short[] disconnect() {
		if (data.length != 1) return Errors.FORMAT.getArray();
		
		short code = NetCommand.DISCONNECT.getCode();
		
		client.disconnect();
		
		return new short[] { code };
	}
	private short[] changeName() {
		if (data.length != 13) return Errors.FORMAT.getArray();
		short code = NetCommand.NAME.getCode();
		
		short[] nameSS = new short[12];
		for (int i = 0; i < nameSS.length; i++) nameSS[i] = data[1 + i];
		String name = CharacterEncoding.CHAR64.encode(Bytes.toBigInteger(nameSS));

		if (name.isEmpty()) name = ClientManager.DEFAULT_NAME;
		
		client.setName(name);
		
		return new short[] { code };
	}
	private short[] register() {
		if (data.length != 1) return Errors.FORMAT.getArray();
		
		short code = NetCommand.REGISTER.getCode();
		
		//TODO: Create method to register client for updates
//		client.register();
		
		return new short[] { code };
	}
	private short[] unregister() {
		if (data.length != 1) return Errors.FORMAT.getArray();
		
		short code = NetCommand.UNREGISTER.getCode();
		
		//TODO: Create method to unregister client from updates
//		client.unregister();
		
		return new short[] { code };
	}
}
